////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001-2010.
// -------------------------------------------------------------------------
//  File name:   UIManager.cpp
//  Version:     v1.00
//  Created:     10/9/2010 by Paul Reindell.
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "UIManager.h"
#include "CustomMessageBox.h"

#include "../HyperGraph/FlowGraph.h"
#include "../HyperGraph/FlowGraphManager.h"

#include "UIEditor.h"
#include "UIViewport.h"

#include <IScaleformGFx.h>

#define UI_ACTIONS_FOLDER "UIActions"
#define GRAPH_FILE_FILTER "Graph XML Files (*.xml)|*.xml"

float CUIManager::CV_gfx_FlashReloadTime = 0;
int CUIManager::CV_gfx_FlashReloadEnabled = 0;

////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
CUIManager::CUIManager()
: m_pEditor(NULL)
{
}

////////////////////////////////////////////////////////////////////
CUIManager::~CUIManager()
{
	GetIEditor()->GetLevelIndependentFileMan()->UnregisterModule(this);
	if (gEnv->pConsole)
		gEnv->pConsole->UnregisterVariable("gfx_FlashReloadTime");
	if (gEnv->pFlashUI)
		gEnv->pFlashUI->UnregisterModule(this);
}

////////////////////////////////////////////////////////////////////
void CUIManager::Init(  )
{
	if (gEnv->pFlashUI)
		gEnv->pFlashUI->RegisterModule(this, "CUIManagerSandbox");
	GetIEditor()->GetLevelIndependentFileMan()->RegisterModule(this);
	ReloadActionGraphs();
	REGISTER_CVAR2("gfx_FlashReloadTime", &CV_gfx_FlashReloadTime, 1.f, VF_NULL, "Time in seconds to wait for flash to publish a file (used for auto-reload of UIEmulator)");
	REGISTER_CVAR2("gfx_FlashReloadEnabled", &CV_gfx_FlashReloadEnabled, 0, VF_NULL, "Enable live reloading of changed flash assets. 0=Disabled, 1=Enabled");
}

////////////////////////////////////////////////////////////////////
bool CUIManager::IsFlashEnabled() const
{
	return gEnv->pScaleformGFx && gEnv->pScaleformGFx->IsScaleformSupported();
}

////////////////////////////////////////////////////////////////////
void CUIManager::ReloadActionGraphs(bool bReloadGraphs)
{
	if (!gEnv->pFlashUI)
		return;

	int i = 0;
	IUIAction* pAction;
	while ( pAction = gEnv->pFlashUI->GetUIAction(i++) )
	{
		if (pAction->GetType() != IUIAction::eUIAT_FlowGraph)
			continue;

		CFlowGraph* pFlowGraph = GetIEditor()->GetFlowGraphManager()->FindGraphForUIAction( pAction );
		bool bReloadAction = bReloadGraphs || !pFlowGraph;
		if ( !pFlowGraph )
		{
			pFlowGraph = GetIEditor()->GetFlowGraphManager()->CreateGraphForUIAction( pAction );
		}
		if (bReloadAction)
		{
			CString filename( GetUIActionFolder() );
			filename += '/';
			filename += pAction->GetName();
			filename += ".xml";
			pFlowGraph->SetName( "" );
			pFlowGraph->Load( filename );
		}
	}
}

////////////////////////////////////////////////////////////////////
void CUIManager::SaveChangedGraphs()
{
	if (!gEnv->pFlashUI)
		return;

	int i = 0;
	IUIAction* pAction;
	while ( pAction = gEnv->pFlashUI->GetUIAction(i++) )
	{
		if (pAction->GetType() != IUIAction::eUIAT_FlowGraph)
			continue;

		CFlowGraph* pFlowGraph = GetIEditor()->GetFlowGraphManager()->FindGraphForUIAction( pAction );
		assert (pFlowGraph);
		if (pFlowGraph && pFlowGraph->IsModified())
		{
			CString filename( GetUIActionFolder() );
			filename += '/';
			filename += pAction->GetName();
			filename += ".xml";
			pFlowGraph->SetName( "" );
			pFlowGraph->Save( filename );
		}
	}
}

////////////////////////////////////////////////////////////////////
bool CUIManager::HasModifications()
{
	if (!gEnv->pFlashUI)
		return false;

	int i = 0;
	IUIAction* pAction;
	while ( pAction = gEnv->pFlashUI->GetUIAction(i++) )
	{
		if (pAction->GetType() != IUIAction::eUIAT_FlowGraph)
			continue;

		CFlowGraph* pFlowGraph = GetIEditor()->GetFlowGraphManager()->FindGraphForUIAction( pAction );
		assert (pFlowGraph);
		if (pFlowGraph && pFlowGraph->IsModified())
			return true;
	}
	return false;
}

////////////////////////////////////////////////////////////////////
bool CUIManager::NewUIAction( CString& filename )
{
	if (!gEnv->pFlashUI)
		return false;

	CFileUtil::CreateDirectory( Path::GetGameFolder() + CString("/") + GetUIActionFolder() );

	if ( !CFileUtil::SelectSaveFile( GRAPH_FILE_FILTER, "xml", Path::GetGameFolder() + CString("/") + GetUIActionFolder(), filename ) )
		return false;

	// check if file exists.
	FILE *file = fopen( filename, "rb" );
	if ( file )
	{
		fclose(file);
		AfxMessageBox( "Can't create UI Action because another UI Action with this name already exists!\n\nCreation canceled..." );
		return false;
	}
	CString luafilename = filename;
	luafilename.Replace(".xml", ".lua");
	file = fopen( luafilename, "rb" );
	if ( file )
	{
		fclose(file);
		AfxMessageBox( "Can't create UI Action because another Lua UI Action with this name already exists!\n\nCreation canceled..." );
		return false;
	}


	// Make a new graph.
	CFlowGraphManager* pManager = GetIEditor()->GetFlowGraphManager();
	CHyperGraph* pGraph = pManager->CreateGraph();

	if ( pGraph->Save( filename ) )
	{
		gEnv->pFlashUI->LoadActionFromFile( filename, IUIAction::eUIAT_FlowGraph );
		ReloadActionGraphs();
		return true;
	}
	return false;
}

////////////////////////////////////////////////////////////////////
void CUIManager::ReloadScripts()
{
	gEnv->pFlashUI->Reload();
}

////////////////////////////////////////////////////////////////////
bool CUIManager::PromptChanges()
{
	if (HasModifications())
	{
		CString msg(_T("Some UIAction flowgraphs are modified!\nDo you want to save your changes?" ) );
		int idx = CCustomMessageBox::Show( msg,_T("UIAction(s) not saved!"), "Cancel" /*idx 1*/, "Don't save" /*idx 2*/, "Save" /*idx 3*/);
		if (idx == 3)
		{
			SaveChangedGraphs();
		}
		else if (idx == 1)
		{
			return false;
		}
	}
	return true;
}

////////////////////////////////////////////////////////////////////
void CUIManager::EnableUpdates(bool bEnabled)
{
	if (GetEditor())
		GetEditor()->GetViewport()->Pause(!bEnabled);
}

////////////////////////////////////////////////////////////////////
CString CUIManager::GetUIActionFolder()
{
	ICVar* pFolderVar = gEnv->pConsole->GetCVar("gfx_uiaction_folder");

	CString folder;
	folder.Format("%s/%s", pFolderVar ? pFolderVar->GetString() : "Libs/UI", UI_ACTIONS_FOLDER);
	return folder;
}

////////////////////////////////////////////////////////////////////
bool CUIManager::EditorAllowReload()
{
	return PromptChanges();
}

////////////////////////////////////////////////////////////////////
void CUIManager::EditorReload()
{
	ReloadActionGraphs(true);
}


